#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include "defs.h"
#include "utils.h"

void box(int x1, int y1, int x2, int y2, int color, int line, int shadow, int text)
{
   int x,y;

   window(x1,y1,x2,y2);
   textbackground(color);
   clrscr();
   textcolor(line); gotoxy(2, 2);   putch(218);
   for(x=3; x<x2-x1; x++) putch(196);
   textcolor(shadow); putch(191);
   for(y=3; y<y2-y1; y++)
     {textcolor(line); gotoxy(2, y);  putch(179);
      textcolor(shadow); gotoxy(x2-x1, y);  putch(179);
     }
   textcolor(line); gotoxy(2, y2-y1); putch(192);
   textcolor(shadow); for (x=3; x<x2-x1; x++) putch(196);
   putch(217);
   textcolor(text);
}

void double_box(int x1, int y1, int x2, int y2, int color, int line, int text)
{
   int x,y;

   window(x1,y1,x2,y2);
   textbackground(color); textcolor(line);
   clrscr();
   gotoxy(2, 2);   putch(201);
   for(x=3; x<x2-x1; x++) putch(205);
   putch(187);
   for(y=3; y<y2-y1; y++)
     {gotoxy(2, y);  putch(186);
      gotoxy(x2-x1, y);  putch(186);
     }
   gotoxy(2, y2-y1); putch(200);
   for (x=3; x<x2-x1; x++) putch(205);
   putch(188);
   textcolor(text);
}

int get_string(char *string, int protect)
{
   int i=0, temp;
   char stemp[10];
   while(i<10)
     {temp=getch();
      if(temp==0) getch();
      if(temp==8 && i>0)
        {i--;
         gotoxy(wherex()-1,wherey()); putch(' ');
         gotoxy(wherex()-1,wherey());
        }
      if(temp==13 || temp==32 || temp==9) //space bar, enter, or tab
        {if(i==0) return NULL;
         for(i=i;i<10;i++) stemp[i]=0;
         sprintf(string,"%s",stemp);
        }
      if(temp==27) return ESC;  //escape
      if(((temp>47 && temp<58) || (temp>64 && temp<91) || (temp>96 && temp<123)) && i<8)
        {if(protect==PASSWORD) putch('*');
         else putch(temp);
         stemp[i++]=temp;
        }
     }
   return 1;
}

int get_string3(char *string)
{
   int i=0, temp;
   char stemp[10];
   while(i<10)
     {temp=getch();
      if(temp==0) getch();
      if(temp==8 && i>0)
        {i--;
         gotoxy(wherex()-1,wherey()); putch(' ');
         gotoxy(wherex()-1,wherey());
        }
      if(temp==13 || temp==32 || temp==9) //space bar, enter, or tab
        {if(i==0) return NULL;
         for(i=i;i<10;i++) stemp[i]=0;
         sprintf(string,"%s",stemp);
        }
      if(temp==27) return ESC;  //escape
      if(temp>32 && temp<127 && i<3)
        {putch(temp);
         stemp[i++]=temp;
        }
     }
   return 1;
}

int get_string_all(char *string)
{
   int i=0, temp;
   char stemp[10];
   while(i<10)
     {temp=getch();
      if(temp==0) getch();
      if(temp==8 && i>0)
        {i--;
         gotoxy(wherex()-1,wherey()); putch(' ');
         gotoxy(wherex()-1,wherey());
        }
      if(temp==13 || temp==32 || temp==9) //space bar, enter, or tab
        {if(i==0) return NULL;
         for(i=i;i<10;i++) stemp[i]=0;
         sprintf(string,"%s",stemp);
        }
      if(temp==27) return ESC;  //escape
      if(temp>32 && temp<127 && i<8)
        {putch(temp);
         stemp[i++]=temp;
        }
     }
   return 1;
}

int get_value(float *value)
{
   int i=0, temp;
   char string[10];
   while(i<10)
     {temp=getch();
      if(temp==8 && i>0)
        {i--;
         gotoxy(wherex()-1,wherey()); putch(' ');
         gotoxy(wherex()-1,wherey());
        }
      if(temp==13 || temp==32 || temp==9) //space bar, enter, or tab
        {if(i==0) return NULL;
         for(i=i;i<10;i++) string[i]=0;
        }
      if(temp==27) return ESC;  //escape
      if((temp==46 || (temp>47 && temp<58)) && i<7)
        {putch(temp);
         string[i++]=temp;
        }
     }
   *value=(float)atof(string);
   return 1;
}

int get_value_all(float *value)
{
   int i=0, temp;
   char string[10];
   while(i<10)
     {temp=getch();
      if(temp==8 && i>0)
        {i--;
         gotoxy(wherex()-1,wherey()); putch(' ');
         gotoxy(wherex()-1,wherey());
        }
      if(temp==13 || temp==32 || temp==9) //space bar, enter, or tab
        {if(i==0) return NULL;
         for(i=i;i<10;i++) string[i]=0;
        }
      if(temp==27) return ESC;  //escape
      if((temp==46 || temp==45 || (temp>47 && temp<58)) && i<7)
        {putch(temp);
         string[i++]=temp;
        }
     }
   *value=(float)atof(string);
   return 1;
}

char *prn_val(float num)
{
   static char string[10];
   if(num<0 || num>=9999999.5)sprintf(string,"%7.5f",0);
   if(num>=0 && num<9.999995)sprintf(string,"%7.5f",num);
   if(num>=9.999995 && num<99.99995)sprintf(string,"%7.4f",num);
   if(num>=99.99995 && num<999.9995)sprintf(string,"%7.3f",num);
   if(num>=999.9995 && num<9999.995)sprintf(string,"%7.2f",num);
   if(num>=9999.995 && num<99999.95)sprintf(string,"%7.1f",num);
   if(num>=99999.95 && num<9999999.5)sprintf(string,"%7.0f",num);
   return string;
}

char *prn_val_all(float num)
{
   char s=' ';
   static char string[10];
   if(num<0) {s='-'; num=fabs(num);}
   if(num<0 || num>=9999999.5)sprintf(string,"%c%7.5f",s,0);
   if(num>=0 && num<9.999995)sprintf(string,"%c%7.5f",s,num);
   if(num>=9.999995 && num<99.99995)sprintf(string,"%c%7.4f",s,num);
   if(num>=99.99995 && num<999.9995)sprintf(string,"%c%7.3f",s,num);
   if(num>=999.9995 && num<9999.995)sprintf(string,"%c%7.2f",s,num);
   if(num>=9999.995 && num<99999.95)sprintf(string,"%c%7.1f",s,num);
   if(num>=99999.95 && num<9999999.5)sprintf(string,"%c%7.0f",s,num);
   return string;
}

void change_pt_units(struct soft_setup *software, struct pos *pt, int new_units, int new_a_units)
{
   if((*software).units==IN && new_units==MM)
     {(*pt).x_pos=(*pt).x_pos*25.4;
      (*pt).y_pos=(*pt).y_pos*25.4;
      (*pt).z_pos=(*pt).z_pos*25.4;
     }
   else if((*software).units==MM && new_units==IN)
     {(*pt).x_pos=(*pt).x_pos/25.4;
      (*pt).y_pos=(*pt).y_pos/25.4;
      (*pt).z_pos=(*pt).z_pos/25.4;
     }
   if((*software).a_units==IN && new_a_units==MM) (*pt).a_pos=(*pt).a_pos*25.4;
   else if((*software).a_units==MM && new_a_units==IN) (*pt).a_pos=(*pt).a_pos/25.4;
   if((*software).a_units==RAD && new_a_units==DEG) (*pt).a_pos=(*pt).a_pos*57.29578;
   else if((*software).a_units==DEG && new_a_units==RAD) (*pt).a_pos=(*pt).a_pos/57.29578;
}

double change_aux_unit(struct soft_setup *software, double dist, int new_a_units)
{
   if((*software).a_units==IN && new_a_units==MM) dist=dist*25.4;
   else if((*software).a_units==MM && new_a_units==IN) dist=dist/25.4;
   if((*software).a_units==RAD && new_a_units==DEG) dist=dist*57.29578;
   else if((*software).a_units==DEG && new_a_units==RAD) dist=dist/57.29578;
   return dist;
}

double change_unit(struct soft_setup *software, double dist, int new_units)
{
   if((*software).a_units==IN && new_units==MM) dist=dist*25.4;
   else if((*software).a_units==MM && new_units==IN) dist=dist/25.4;
   return dist;
}

void rotate_x(struct soft_setup *software, struct hard_setup *hardware, struct pos *pt)
{
   double dtemp;
   float ftemp;
   int itemp;

   //switch all hardware values as if rotating +90
   itemp=(*hardware).y_sbit; (*hardware).y_sbit=(*hardware).z_sbit; (*hardware).z_sbit=itemp;
   itemp=(*hardware).y_dbit; (*hardware).y_dbit=(*hardware).z_dbit; (*hardware).z_dbit=itemp;
   itemp=(*hardware).y_lbit; (*hardware).y_lbit=(*hardware).z_lbit; (*hardware).z_lbit=itemp;
   itemp=(*hardware).y_ltrip; (*hardware).y_ltrip=(*hardware).z_ltrip; (*hardware).z_ltrip=itemp;
   itemp=(*hardware).y_ltrip; (*hardware).y_ltrip=(*hardware).z_ltrip; (*hardware).z_ltrip=itemp;
   itemp=(*hardware).y_pdir; (*hardware).y_pdir=(*hardware).z_pdir;
   if(itemp==HIGH) itemp=LOW; else itemp=HIGH; (*hardware).z_pdir=itemp;
   ftemp=(*hardware).accel_y; (*hardware).accel_y=(*hardware).accel_z; (*hardware).accel_z=ftemp;
   ftemp=(*hardware).vel_y; (*hardware).vel_y=(*hardware).vel_z; (*hardware).vel_z=ftemp;
   ftemp=(*hardware).h_spd_y; (*hardware).h_spd_y=(*hardware).h_spd_z; (*hardware).h_spd_z=ftemp;
   ftemp=(*hardware).min_vel_y; (*hardware).min_vel_y=(*hardware).min_vel_z; (*hardware).min_vel_z=ftemp;
   ftemp=(*hardware).y_per_step; (*hardware).y_per_step=(*hardware).z_per_step; (*hardware).z_per_step=ftemp;
   ftemp=(*hardware).debo_y; (*hardware).debo_y=(*hardware).debo_z; (*hardware).debo_z=ftemp;
   ftemp=(*hardware).len_y; (*hardware).len_y=(*hardware).len_z; (*hardware).len_z=ftemp;
   ftemp=(*hardware).back_y; (*hardware).back_y=(*hardware).back_z; (*hardware).back_z=ftemp;

   //switch all software values as if rotating +90
   ftemp=(*software).fjog_y; (*software).fjog_y=(*software).fjog_z; (*software).fjog_z=ftemp;
   ftemp=(*software).sjog_y; (*software).sjog_y=(*software).sjog_z; (*software).sjog_z=ftemp;
   ftemp=(*software).home_y; (*software).home_y=(*software).home_z; (*software).home_z=ftemp;

   //switch coordinates as if rotating +90
   dtemp=(*pt).y_pos; (*pt).y_pos=(*pt).z_pos; (*pt).z_pos=-dtemp;
}

void rotate_y(struct soft_setup *software, struct hard_setup *hardware, struct pos *pt)
{
   double dtemp;
   float ftemp;
   int itemp;

   //switch all hardware values as if rotating +90
   itemp=(*hardware).z_sbit; (*hardware).z_sbit=(*hardware).x_sbit; (*hardware).x_sbit=itemp;
   itemp=(*hardware).z_dbit; (*hardware).z_dbit=(*hardware).x_dbit; (*hardware).x_dbit=itemp;
   itemp=(*hardware).z_lbit; (*hardware).z_lbit=(*hardware).x_lbit; (*hardware).x_lbit=itemp;
   itemp=(*hardware).z_ltrip; (*hardware).z_ltrip=(*hardware).x_ltrip; (*hardware).x_ltrip=itemp;
   itemp=(*hardware).z_ltrip; (*hardware).z_ltrip=(*hardware).x_ltrip; (*hardware).x_ltrip=itemp;
   itemp=(*hardware).z_pdir; (*hardware).z_pdir=(*hardware).x_pdir;
   if(itemp==HIGH) itemp=LOW; else itemp=HIGH; (*hardware).x_pdir=itemp;
   ftemp=(*hardware).accel_z; (*hardware).accel_z=(*hardware).accel_x; (*hardware).accel_x=ftemp;
   ftemp=(*hardware).vel_z; (*hardware).vel_z=(*hardware).vel_x; (*hardware).vel_x=ftemp;
   ftemp=(*hardware).h_spd_z; (*hardware).h_spd_z=(*hardware).h_spd_x; (*hardware).h_spd_x=ftemp;
   ftemp=(*hardware).min_vel_z; (*hardware).min_vel_z=(*hardware).min_vel_x; (*hardware).min_vel_x=ftemp;
   ftemp=(*hardware).z_per_step; (*hardware).z_per_step=(*hardware).x_per_step; (*hardware).x_per_step=ftemp;
   ftemp=(*hardware).debo_z; (*hardware).debo_z=(*hardware).debo_x; (*hardware).debo_x=ftemp;
   ftemp=(*hardware).len_z; (*hardware).len_z=(*hardware).len_x; (*hardware).len_x=ftemp;
   ftemp=(*hardware).back_z; (*hardware).back_z=(*hardware).back_x; (*hardware).back_x=ftemp;

   //switch all software values as if rotating +90
   ftemp=(*software).fjog_z; (*software).fjog_z=(*software).fjog_x; (*software).fjog_x=ftemp;
   ftemp=(*software).sjog_z; (*software).sjog_z=(*software).sjog_x; (*software).sjog_x=ftemp;
   ftemp=(*software).home_z; (*software).home_z=(*software).home_x; (*software).home_x=ftemp;

   //switch coordinates as if rotating +90
   dtemp=(*pt).z_pos; (*pt).z_pos=(*pt).x_pos; (*pt).x_pos=-dtemp;
}

void rotate_z(struct soft_setup *software, struct hard_setup *hardware, struct pos *pt)
{
   double dtemp;
   float ftemp;
   int itemp;

   //switch all hardware values as if rotating +90
   itemp=(*hardware).x_sbit; (*hardware).x_sbit=(*hardware).y_sbit; (*hardware).y_sbit=itemp;
   itemp=(*hardware).x_dbit; (*hardware).x_dbit=(*hardware).y_dbit; (*hardware).y_dbit=itemp;
   itemp=(*hardware).x_lbit; (*hardware).x_lbit=(*hardware).y_lbit; (*hardware).y_lbit=itemp;
   itemp=(*hardware).x_ltrip; (*hardware).x_ltrip=(*hardware).y_ltrip; (*hardware).y_ltrip=itemp;
   itemp=(*hardware).x_ltrip; (*hardware).x_ltrip=(*hardware).y_ltrip; (*hardware).y_ltrip=itemp;
   itemp=(*hardware).x_pdir; (*hardware).x_pdir=(*hardware).y_pdir;
   if(itemp==HIGH) itemp=LOW; else itemp=HIGH; (*hardware).y_pdir=itemp;
   ftemp=(*hardware).accel_x; (*hardware).accel_x=(*hardware).accel_y; (*hardware).accel_y=ftemp;
   ftemp=(*hardware).vel_x; (*hardware).vel_x=(*hardware).vel_y; (*hardware).vel_y=ftemp;
   ftemp=(*hardware).h_spd_x; (*hardware).h_spd_x=(*hardware).h_spd_y; (*hardware).h_spd_y=ftemp;
   ftemp=(*hardware).min_vel_x; (*hardware).min_vel_x=(*hardware).min_vel_y; (*hardware).min_vel_y=ftemp;
   ftemp=(*hardware).x_per_step; (*hardware).x_per_step=(*hardware).y_per_step; (*hardware).y_per_step=ftemp;
   ftemp=(*hardware).debo_x; (*hardware).debo_x=(*hardware).debo_y; (*hardware).debo_y=ftemp;
   ftemp=(*hardware).len_x; (*hardware).len_x=(*hardware).len_y; (*hardware).len_y=ftemp;
   ftemp=(*hardware).back_x; (*hardware).back_x=(*hardware).back_y; (*hardware).back_y=ftemp;

   //switch all software values as if rotating +90
   ftemp=(*software).fjog_x; (*software).fjog_x=(*software).fjog_y; (*software).fjog_y=ftemp;
   ftemp=(*software).sjog_x; (*software).sjog_x=(*software).sjog_y; (*software).sjog_y=ftemp;
   ftemp=(*software).home_x; (*software).home_x=(*software).home_y; (*software).home_y=ftemp;

   //switch coordinates as if rotating +90
   dtemp=(*pt).x_pos; (*pt).x_pos=(*pt).y_pos; (*pt).y_pos=-dtemp;
}

void switch_z_a(struct soft_setup *software, struct hard_setup *hardware, struct pos *pt)
{
   double dtemp;
   float ftemp;
   int itemp;

   //switch all hardware values as if rotating +90
   itemp=(*hardware).z_sbit; (*hardware).z_sbit=(*hardware).a_sbit; (*hardware).a_sbit=itemp;
   itemp=(*hardware).z_dbit; (*hardware).z_dbit=(*hardware).a_dbit; (*hardware).a_dbit=itemp;
   itemp=(*hardware).z_lbit; (*hardware).z_lbit=(*hardware).a_lbit; (*hardware).a_lbit=itemp;
   itemp=(*hardware).z_ltrip; (*hardware).z_ltrip=(*hardware).a_ltrip; (*hardware).a_ltrip=itemp;
   itemp=(*hardware).z_ltrip; (*hardware).z_ltrip=(*hardware).a_ltrip; (*hardware).a_ltrip=itemp;
   itemp=(*hardware).z_pdir; (*hardware).z_pdir=(*hardware).a_pdir;
   if(itemp==HIGH) itemp=LOW; else itemp=HIGH; (*hardware).a_pdir=itemp;
   ftemp=(*hardware).accel_z; (*hardware).accel_z=(*hardware).accel_a; (*hardware).accel_a=ftemp;
   ftemp=(*hardware).vel_z; (*hardware).vel_z=(*hardware).vel_a; (*hardware).vel_a=ftemp;
   ftemp=(*hardware).h_spd_z; (*hardware).h_spd_z=(*hardware).h_spd_a; (*hardware).h_spd_a=ftemp;
   ftemp=(*hardware).min_vel_z; (*hardware).min_vel_z=(*hardware).min_vel_a; (*hardware).min_vel_a=ftemp;
   ftemp=(*hardware).z_per_step; (*hardware).z_per_step=(*hardware).a_per_step; (*hardware).a_per_step=ftemp;
   ftemp=(*hardware).debo_z; (*hardware).debo_z=(*hardware).debo_a; (*hardware).debo_a=ftemp;
   ftemp=(*hardware).len_z; (*hardware).len_z=(*hardware).len_a; (*hardware).len_a=ftemp;
   ftemp=(*hardware).back_z; (*hardware).back_z=(*hardware).back_a; (*hardware).back_a=ftemp;

   //switch all software values as if rotating +90
   ftemp=(*software).fjog_z; (*software).fjog_z=(*software).fjog_a; (*software).fjog_a=ftemp;
   ftemp=(*software).sjog_z; (*software).sjog_z=(*software).sjog_a; (*software).sjog_a=ftemp;
   ftemp=(*software).home_z; (*software).home_z=(*software).home_a; (*software).home_a=ftemp;

   //switch coordinates as if rotating +90
   //dtemp=(*pt).z_pos; (*pt).z_pos=(*pt).a_pos; (*pt).a_pos=dtemp;
}
